
/**
  ******************************************************************************
  * Copyright 2021 The grapilot Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       gp_time.c
  * @author     baiyang
  * @date       2021-7-8
  ******************************************************************************
  */

/*----------------------------------include-----------------------------------*/
#include "gp_time.h"

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL_WIN
#include <stdio.h>
#include <windows.h>
#else
#include "stm32f4xx_ll_rcc.h"
#endif

/*-----------------------------------macro------------------------------------*/

/*----------------------------------typedef-----------------------------------*/

/*---------------------------------prototype----------------------------------*/

/*----------------------------------variable----------------------------------*/
Time_def time_conversion_factor;
/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/

/**
  * @brief       
  * @param[in]   time_ms  
  * @param[out]  
  * @retval      
  * @note        
  */
void time_delay_ms(uint32_t time_ms)
{
    time_delay_us(time_ms * 1000);
}

/**
  * @brief       
  * @param[in]   time_us  
  * @param[out]  
  * @retval      
  * @note        
  */
void time_delay_us(uint32_t time_us)
{
    uint64_t target = time_micros64() + time_us;

    while (time_micros64() < target)
        ;
}

/**
  * @brief       
  * @param[in]   timetag  
  * @param[out]  
  * @retval      
  * @note        
  */
uint8_t time_check_tag(TimeTag* timetag)
{
    uint32_t now = time_millis();

    if (now - timetag->tag >= timetag->period) {
        timetag->tag = now;

        return 1;
    }

    return 0;
}

/**
  * @brief       
  * @param[in]   timetag  
  * @param[in]   now  
  * @param[out]  
  * @retval      
  * @note        
  */
uint8_t time_check_tag2(TimeTag* timetag, uint32_t now)
{
    if (now - timetag->tag >= timetag->period) {
        timetag->tag = now;

        return 1;
    }

    return 0;
}

/**
  * @brief       
  * @param[in]   timetag  
  * @param[in]   now  
  * @param[in]   period  
  * @param[out]  
  * @retval      
  * @note        
  */
uint8_t time_check_tag3(TimeTag* timetag, uint32_t now, uint32_t period)
{
    if (now - timetag->tag >= period) {
        timetag->tag = now;

        return 1;
    }

    return 0;
}

/**
  * @brief       
  * @param[in]   
  * @param[out]  
  * @retval      
  * @note        
  */
void time_init(void)
{
#if CONFIG_HAL_BOARD != HAL_BOARD_SITL_WIN
    time_conversion_factor.ticksPerUs = HAL_RCC_GetSysClockFreq() / 1e6;       //???     
    time_conversion_factor.ticksPerMs = HAL_RCC_GetSysClockFreq() / 1e3;       //??? baiyang    
#endif
}

/**
  * @brief       获取当前时间，us。
  * @param[in]   
  * @param[out]  
  * @retval      
  * @note        
  */
uint64_t time_micros64(void)
{
    uint64_t us = 0;

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL_WIN
    // windows下微秒时间为毫秒*1000
    us = (uint64_t)((float)rt_tick_get()/RT_TICK_PER_SECOND*1000) * (uint64_t)1000;
#else
    volatile uint64_t t1 = (SysTick->LOAD - SysTick->VAL) / time_conversion_factor.ticksPerUs;
    volatile uint64_t t2 = (uint64_t)((float)rt_tick_get()/RT_TICK_PER_SECOND*1000) * (uint64_t)1000;
    volatile uint64_t t3 = (SysTick->LOAD - SysTick->VAL) / time_conversion_factor.ticksPerUs;
    volatile uint64_t t4 = (uint64_t)((float)rt_tick_get()/RT_TICK_PER_SECOND*1000) * (uint64_t)1000;

    if (t1 > t3) {
        us = t3 + t4;
    } else {
        us = t3 + t2;
    }
#endif

    return us;
}

/**
  * @brief       获取当前时间，us。
  * @param[in]   
  * @param[out]  
  * @retval      
  * @note        
  */
uint32_t time_micros(void)
{
    return (uint32_t)time_micros64();
}

/**
  * @brief       获取当前时间，ms。
  * @param[in]   
  * @param[out]  
  * @retval      
  * @note        
  */
uint32_t time_millis(void)
{
    return time_micros64()*0.001f;
}

/**
  * @brief       获取当前时间，ms。
  * @param[in]   
  * @param[out]  
  * @retval      
  * @note        
  */
uint16_t time_millis16(void)
{
    return time_micros64()*0.001f;
}

/**
  * @brief       获取当前时间，ms。
  * @param[in]   
  * @param[out]  
  * @retval      
  * @note        
  */
uint64_t time_millis64(void)
{
    return time_micros64()*0.001;
}
/*------------------------------------test------------------------------------*/


